package lookas;

import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

public class PeselGenerator{
    private static final List<Integer> TABLE = Arrays.asList(1, 3, 7, 9, 1, 3, 7, 9, 1, 3);
    private Calendar                   minYear;
    private Calendar                   maxYear;
    private static final Random        RAND  = new Random();

    public String next(){
        return next(RAND.nextInt(10));
    }

    public String next(int sex){
        long min = minYear.getTimeInMillis();
        long max = maxYear.getTimeInMillis();

        GregorianCalendar calendar = new GregorianCalendar();
        long l = max - min;
        if(l < 0){
            l = max;
            max = min;
            min = l;
            l = max - min;
        }
        long r = (long)(RAND.nextDouble() * l);
        calendar.setTimeInMillis(r + min);

        return generate(calendar, sex);
    }

    public static String generate(Calendar date, int sex){
        Iterator<Integer> tab = TABLE.iterator();
        StringBuilder pesel = new StringBuilder();
        int sum = 0;
        byte z;
        {
            int year = date.get(Calendar.YEAR);
            int x = year / 100;
            x += 1;
            x *= 2;
            x %= 10;
            year = year % 100;
            z = (byte)(year / 10);
            sum += z * tab.next();
            pesel.append(z);
            z = (byte)(year % 10);
            sum += z * tab.next();
            pesel.append(z);
            int month = date.get(Calendar.MONTH) + 1;
            month += x * 10;
            z = (byte)(month / 10);
            sum += z * tab.next();
            pesel.append(z);
            z = (byte)(month % 10);
            sum += z * tab.next();
            pesel.append(z);
            int day = date.get(Calendar.DAY_OF_MONTH);
            z = (byte)(day / 10);
            sum += z * tab.next();
            pesel.append(z);
            z = (byte)(day % 10);
            sum += z * tab.next();
            pesel.append(z);
        }
        {
            for(int i = 0; i < 3; i++){
                z = (byte)RAND.nextInt(10);
                sum += z * tab.next();
                pesel.append(z);
            }
            int x = RAND.nextInt(5) * 2 + sex;
            x %= 10;
            z = (byte)x;
            sum += z * tab.next();
            pesel.append(z);
        }
        {
            sum %= 10;
            sum = 10 - sum;
            sum %= 10;
            pesel.append((byte)sum);
        }
        return pesel.toString();
    }

    public void setMaxYear(Calendar maxYear){
        this.maxYear = maxYear;
    }

    public Calendar getMaxYear(){
        return maxYear;
    }

    public void setMinYear(Calendar minYear){
        this.minYear = minYear;
    }

    public Calendar getMinYear(){
        return minYear;
    }
}
